
#include "pwm.h"
#include "hal_mcu.h"

void pwm_init(void)
{
	T1CTL = 0x00; // STOP TIMER1 

	//set TIMER1 CLOCK to 32M
	CLKCONCMD = (CLKCONCMD & 0x80) | (TICKSPD(0) | CLKSPD(0));							  
	while ( (CLKCONSTA & ~0x80) != (TICKSPD(0) | CLKSPD(0))); 
		
	P0DIR |= BV(2)| BV(3)|BV(4)|BV(5);		//set p0_4,P0_5,P0_6 to output
	//P2DIR |= BV(6)|BV(7);			//priority:Timer 1 channels 2-3
	P0SEL|= BV(2)| BV(3)|BV(4)|BV(5);		//set pin to per
	PERCFG |= 0x03; 				// T1&t3&t4 Alt 1, usart0 & usart1 Alt2 
	
	T1CCTL0 = 0x6c;//0x6c;		//channel 0	mode:101: Reserved
	T1CCTL1 = 0x6c;//0x6c;		//channel 0	mode:101: Reserved
	T1CCTL2 = 0x6c;//0x6c;		//channel 2	mode:101: Clear when equal T1CC0, set when equal T1CC1
	T1CCTL3 = 0x6c;//0x6c;		//channel 3	mode:101: Clear when equal T1CC0, set when equal T1CC1
	//T1CCTL4 = 0x6c;//0x6c;		//channel 4	mode:101: Clear when equal T1CC0, set when equal T1CC1
}

void pwm_start(void)
{
	T1CNTL = 0x00; // Reset timer to 0;
	T1CNTH = 0x00; // Reset timer to 0;
	T1CTL = 0x0e; // 1/(32M/128) = 4us, MODE = module  start T1
}

void pwm_stop(void)
{
	T1CTL = 0x00; // STOP TIMER1 
	T1CNTL = 0x00; // Reset timer to 0;
	T1CNTH = 0x00; // Reset timer to 0;

	//P0DIR &= ~(BV(4)|BV(5)|BV(6));		//set p0_4,P0_5,P0_6 to iutput
	//P0SEL &= ~(BV(4)|BV(5)|BV(6));		//set pin to GPIO
}

//p0_2 channel 0
void set_dutycycle_L(uint8 duty_cycle)
{
	if(duty_cycle > 100)
	{
		return;
	}
	else if(duty_cycle == 100)
	{
		T1CCTL0 = 0x04;		//channel 0	mode:000: Set output on compare
	}
	else if(duty_cycle == 0)
	{
		T1CCTL0 = 0x0c;		//channel 0	mode:000: Set output on compare
	}
	else
	{
		T1CCTL0 = 0x6c;
		duty_cycle = 100 - duty_cycle;
	}

	uint16 period;
	uint8 t1_h = T1CC0H;
	uint8 t1_l = T1CC0L;
	period =  (((uint16)t1_h << 8) | (uint16)t1_l);

	uint16 tmp = (period/100) * duty_cycle;

	T1CC0L = tmp%256;
	T1CC0H = tmp/256;
}

//p0_3 channel 1
void set_dutycycle_l(uint8 duty_cycle)
{
	if(duty_cycle > 100)
	{
		return;
	}
	else if(duty_cycle == 100)
	{
		T1CCTL1 = 0x04;		//channel 2	mode:000: Set output on compare
	}
	else if(duty_cycle == 0)
	{
		T1CCTL1 = 0x0c;		//channel 2	mode:000: Set output on compare
	}
	else
	{
		T1CCTL1 = 0x6c;
		duty_cycle = 100 - duty_cycle;
	}

	uint16 period;
	uint8 t1_h = T1CC0H;
	uint8 t1_l = T1CC0L;
	period =  (((uint16)t1_h << 8) | (uint16)t1_l);

	uint16 tmp = (period/100) * duty_cycle;

	T1CC1L = tmp%256;
	T1CC1H = tmp/256;
}

//p0_4 channel 2
void set_dutycycle_R(uint8 duty_cycle)
{
	if(duty_cycle > 100)
	{
		return;
	}
	else if(duty_cycle == 100)
	{
		T1CCTL2 = 0x04;		//channel 2	mode:000: Set output on compare
	}
	else if(duty_cycle == 0)
	{
		T1CCTL2 = 0x0c;		//channel 2	mode:000: Set output on compare
	}
	else
	{
		T1CCTL2 = 0x6c;
		duty_cycle = 100 - duty_cycle;
	}

	uint16 period;
	uint8 t1_h = T1CC0H;
	uint8 t1_l = T1CC0L;
	period =  (((uint16)t1_h << 8) | (uint16)t1_l);

	uint16 tmp = (period/100) * duty_cycle;

	T1CC2L = tmp%256;
	T1CC2H = tmp/256;
}

//p0_5 channel 3
void set_dutycycle_r(uint8 duty_cycle)
{
	if(duty_cycle > 100)
	{
		return;
	}
	else if(duty_cycle == 100)
	{
		T1CCTL3 = 0x04;		//channel 3	mode:000: Set output on compare
	}
	else if(duty_cycle == 0)
	{
		T1CCTL3 = 0x0c;		//channel 3	mode:000: Set output on compare
	}
	else
	{
		T1CCTL3 = 0x6c;
		duty_cycle = 100 - duty_cycle;
	}

	uint16 period;
	uint8 t1_h = T1CC0H;
	uint8 t1_l = T1CC0L;
	period =  (((uint16)t1_h << 8) | (uint16)t1_l);

	uint16 tmp = (period/100) * duty_cycle;

	T1CC3L = tmp%256;
	T1CC3H = tmp/256;
}

//p0_6 channel 4
void set_dutycycle_b(uint8 duty_cycle)
{
	if(duty_cycle > 100)
	{
		return;
	}
	else if(duty_cycle == 100)
	{
		T1CCTL4 = 0x04;		//channel 4	mode:000: Set output on compare
	}
	else if(duty_cycle == 0)
	{
		T1CCTL4 = 0x0c;		//channel 4	mode:000: Set output on compare
	}
	else
	{
		T1CCTL4 = 0x6c;
		duty_cycle = 100 - duty_cycle;
	}

	uint16 period;
	uint8 t1_h = T1CC0H;
	uint8 t1_l = T1CC0L;
	period =  (((uint16)t1_h << 8) | (uint16)t1_l);

	uint16 tmp = (period/100) * duty_cycle;

	T1CC4L = tmp%256;
	T1CC4H = tmp/256;
}

// 50Hz<=f<=8kHz      1/(32M/128) = 4us
//period unit:ms
void set_pwm_period(uint8 period)
{
	uint16 cnt = (1000/4) * period;
	
	T1CC0L = cnt%256;
	T1CC0H = cnt/256;
}

